//
//  USChatController.m
//  us
//
//  Created by karry on 2025/4/6.
//

#import "USChatController.h"
#import "USChatCellFactory.h"
#import "USChatTheme.h"
#import "USChatToolBar.h"
#import "USChatController+IM.h"
#import <Photos/Photos.h>
#import <PhotosUI/PhotosUI.h>
#import "USMsgTouchIncident.h"
#import "USStickerPickerView.h"
#import "USChatThemeController.h"
#import "USUserInfoViewController.h"
#import "EaseDateHelper.h"
#import "EMAudioRecordUtil.h"
#import "EMAudioPlayerUtil.h"
#import "USStickerModel.h"

@interface USChatController ()<UITableViewDataSource,UITableViewDelegate,PHPickerViewControllerDelegate,USChatCellDelegate,USStickerPickerViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>


@property (nonatomic,strong) UIImageView *backgroundImageView;

@property (nonatomic,strong) USChatToolBar *chatToolBar;

@property (nonatomic,strong) USStickerPickerView *stickerView;

@property (nonatomic, assign) UIEdgeInsets originalContentInset;

@property (nonatomic, assign) CGFloat keyboardHeight;


@property (nonatomic, assign) BOOL isLoadingMore;
@property (nonatomic, assign) BOOL hasMoreData;

@property (nonatomic) BOOL isEmjBarVisible;

@end

@implementation USChatController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    
    [self setupUI];
    
    [self initConversation];
    
    [self setupGesture];
        
    [self setupRAC];
     
}


- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.tableView reloadData];

    //0默认格子，1纯色，2自定义图片
    if (USUser.user.imBgType == 2 && USUser.user.imPhoto.length > 0) {
        self.backgroundImageView.hidden = NO;
        [self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:USUser.user.imPhoto] placeholderImage:[USChatTheme defaultTheme].bgImage];
    }else if (USUser.user.imBgType == 1 && USUser.user.imColor.length > 0){
        self.view.backgroundColor = [UIColor jk_colorWithHexString:USUser.user.imColor];
        self.backgroundImageView.hidden = YES;
    }else{
        self.view.backgroundColor = [UIColor mi_3_color];
        self.backgroundImageView.hidden = NO;
        self.backgroundImageView.image = [USChatTheme defaultTheme].bgImage;
    }
    
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    [EMAudioRecordUtil.sharedHelper cancelRecord];
    [[EMAudioPlayerUtil sharedHelper] stopPlayer];

}
- (void)dealloc {
    [[EMAudioPlayerUtil sharedHelper] stopPlayer];
}
- (void)setupUI{
    

    NSInteger days = 1;
    if (USUser.user.chatDays > 0) {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDate *anniversaryDate = [calendar startOfDayForDate:[NSDate dateWithTimeIntervalSince1970:USUser.user.chatDays]];
        days = [[NSDate now] jk_daysAfterDate:anniversaryDate] + 1;
    }
    UILabel *titleLabel = [[UILabel alloc] init];
    titleLabel.font = [UIFont boldSystemFontOfSize:16];
    titleLabel.text = [NSString stringWithFormat:@"已聊%li天",days];
    titleLabel.userInteractionEnabled = YES; // 必须开启

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(titleLongPressed:)];
    longPress.minimumPressDuration = 2.0;
    [titleLabel addGestureRecognizer:longPress];

    self.navigationItem.titleView = titleLabel;
    
    self.backgroundImageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
    self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
    [self.view addSubview:self.backgroundImageView];
    [self.backgroundImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
    }];
    //设置背景
    self.backgroundImageView.image = [USChatTheme defaultTheme].bgImage;
    
    
    self.tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.backgroundColor = UIColor.clearColor;
    [self.view addSubview:self.tableView];
    [USChatCellFactory registerAllCellsForTableView:self.tableView];
    self.originalContentInset = self.tableView.contentInset;
    
    
    CGFloat toolBarHeight = 36 + 8 * 2;

    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.mas_offset(0);
        make.top.mas_equalTo(self.view.mas_safeAreaLayoutGuideTop);
        
        make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).mas_offset(-12 - toolBarHeight);

    }];
    
    
    self.chatToolBar = [[USChatToolBar alloc]initWithFrame:CGRectMake(0, 0, 200, toolBarHeight)];
    @weakify(self)
    self.chatToolBar.didTapSendBlock = ^(NSString * _Nonnull text) {
        @strongify(self)
        [self m_sendText:text];
    };
    
    self.chatToolBar.didTapSendVoiceBlock = ^(NSString * _Nonnull filePath, NSInteger aTimeLength, NSArray *volumes) {
        @strongify(self)
        [USFeedbackTool impactRigid];
        [self m_sendVoiceWithFilePath:filePath timeLength:aTimeLength volumes:volumes];
    };
    
    self.chatToolBar.didSizeChangeBlock = ^{
        @strongify(self)
        [self updateTableInsetWithDuration:0.0 options:UIViewAnimationOptionCurveEaseInOut completion:nil];
    };
    
    self.chatToolBar.didEmjBlock = ^(BOOL showEmj) {
        @strongify(self)
        [USFeedbackTool impactSoft];
        [self setIsEmjBarVisible:showEmj];
    };
    
    self.chatToolBar.didTextBeginChangeBlock = ^{
        @strongify(self)
        self.isEmjBarVisible = NO;
    };
    
    [[self.chatToolBar.photoBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
        @strongify(self)
        [self photoAction:x];
        
    }];
    
    [self.view addSubview:self.chatToolBar];
    
    [self.chatToolBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self.view.mas_safeAreaLayoutGuideLeft).mas_offset(12);
        make.right.mas_equalTo(self.view.mas_safeAreaLayoutGuideRight).mas_offset(-12);
        make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).mas_offset(-12);
    }];
    
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"chat_theme_set"] style:UIBarButtonItemStylePlain target:self action:@selector(themeAction:)];
    

    dispatch_async(dispatch_get_main_queue(), ^{
        [self updateTableInsetWithDuration:0.0 options:UIViewAnimationOptionCurveEaseInOut completion:nil];
        [self.view addSubview:self.stickerView];
    });
    
}

- (void)titleLongPressed:(UILongPressGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateBegan) {
        [USFeedbackTool notifyWarning];

        MOAlertBaseView *alert = [[MOAlertBaseView alloc]initWithTitle:@"您确定要清空聊天记录吗？" detailTitle:@"清空之后不能恢复" contentView:nil leftButtonImageName:nil rightButtonImageName:nil autoDissmiss:YES tapDissmiss:YES];
        @weakify(self)
        alert.didClickIndexBlock = ^(NSInteger index) {
            @strongify(self)
            if (index == 1) {
                // 获取会话
                EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:self.conversationId
                                                                                               type:EMConversationTypeChat
                                                                                   createIfNotExist:YES];

                // 删除消息
                [conversation deleteAllMessages:nil];
                [self.messageList removeAllObjects];
                [self.tableView reloadData];
            }
        };
        alert.titleLabel.textColor = UIColor.us_redColor;
        [alert show];
    }
}

- (USStickerPickerView *)stickerView {
    if (_stickerView == nil) {

        CGFloat stickerViewH = 324 + 12 + self.view.window.safeAreaInsets.bottom;
        self.stickerView = [[USStickerPickerView alloc]initWithStickerShowCloseButton:NO];
        
        self.stickerView.delegate = self;
        [self.view addSubview:self.stickerView];
        self.stickerView.hidden = YES;
 
        [self.stickerView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(self.view.mas_safeAreaLayoutGuideLeft);
            make.right.mas_equalTo(self.view.mas_safeAreaLayoutGuideRight);
            make.bottom.mas_offset(stickerViewH);
            make.height.mas_equalTo(stickerViewH);
        }];
        
    }
    return _stickerView;
}
 

- (void)setupRAC {
    @weakify(self)
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil]
     subscribeNext:^(NSNotification * _Nullable notification) {
        @strongify(self)
        
        CGRect endFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        UIViewAnimationOptions options = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16;
        
        CGFloat screenHeight = UIScreen.mainScreen.bounds.size.height;
        CGFloat keyboardHeight = MAX(0, screenHeight - endFrame.origin.y); // 收起时为 0
        
        [[NSNotificationCenter defaultCenter] postNotificationName:USNotificationTarget object:nil];

        self.keyboardHeight  = keyboardHeight;
        
        if (self.isEmjBarVisible) {
            return;
        }
        
        [self.chatToolBar mas_updateConstraints:^(MASConstraintMaker *make) {
            if (keyboardHeight > 0 && !self.isEmjBarVisible) {
                // 键盘弹出 & 没有表情栏：贴在键盘上
                make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-keyboardHeight - 12 + self.view.safeAreaInsets.bottom);
            } else if (self.isEmjBarVisible) {
                // 显示了表情栏，不受键盘影响
                make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-self.stickerView.jk_height - 12 + self.view.safeAreaInsets.bottom);
            } else {
                // 默认收起状态
                make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
                
            }
        }];
        
        [self updateTableInsetWithDuration:duration options:options completion:nil];
        
    }];
}

- (void)updateTableInsetWithDuration:(CGFloat)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion{
    
    // 修改 tableView 的 contentInset 和 scrollIndicatorInset

    UIEdgeInsets inset = self.originalContentInset;
    
    if (self.isEmjBarVisible) {
    
        inset.bottom += self.stickerView.jk_height /*+ self.chatToolBar.jk_height + 12*/ - self.view.safeAreaInsets.bottom; // ToolBar 高度
        
    }else{
        
        if (self.keyboardHeight > 0) {
            inset.bottom += self.keyboardHeight /*+ self.chatToolBar.jk_height + 12*/ - self.view.safeAreaInsets.bottom; // ToolBar 高度
        }else{
            inset.bottom += self.keyboardHeight /*+ self.chatToolBar.jk_height + 12*/; // ToolBar 高度
        }
    }
    
    self.tableView.contentInset = inset;
    self.tableView.scrollIndicatorInsets = inset;
    
    [UIView animateWithDuration:duration delay:0 options:options animations:^{
        [self.view layoutIfNeeded];
        if (self.keyboardHeight > 0 || self.isEmjBarVisible) {
            [self scrollToBottomAnimated:NO];
        }
    } completion:completion];
    
}

- (void)setIsEmjBarVisible:(BOOL)isEmjBarVisible{
    
    if (_isEmjBarVisible == isEmjBarVisible) {
        return;
    }
    
    _isEmjBarVisible = isEmjBarVisible;
    
    self.chatToolBar.emjBtn.selected = isEmjBarVisible;
    
    if (isEmjBarVisible) {
        
        [self.chatToolBar.textView resignFirstResponder];
        
        self.stickerView.hidden = NO;
        
        [self.view bringSubviewToFront:self.stickerView];
        
        [self.chatToolBar mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(- self.stickerView.jk_height - 12 + self.view.safeAreaInsets.bottom);
        }];
        
        [self.stickerView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.mas_offset(0);
        }];

        [self updateTableInsetWithDuration:0.3 options:UIViewAnimationOptionCurveEaseInOut completion:nil];
        
    }else{

        [self.stickerView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.mas_offset(self.stickerView.jk_height);
        }];
        
        if (self.chatToolBar.textView.isFirstResponder) {
            [UIView animateWithDuration:0.3 animations:^{
                [self.view layoutIfNeeded];
            }completion:^(BOOL finished) {
                self.stickerView.hidden = YES;
            }];
            return;
        }
    
        [self.chatToolBar mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
        }];
    
        [self updateTableInsetWithDuration:0.3 options:UIViewAnimationOptionCurveEaseInOut completion:^(BOOL finished) {
            self.stickerView.hidden = YES;
        }];

    }
    
}




- (void)scrollToBottomAnimated:(BOOL)animated {
    if (self.messageList.count == 0) return;
    
    NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messageList.count - 1 inSection:0];
    [self.tableView scrollToRowAtIndexPath:lastIndexPath
                          atScrollPosition:UITableViewScrollPositionBottom
                                  animated:animated];
}

- (void)setupGesture{
    
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
    [self.tableView addGestureRecognizer:tapGesture];
    
}

 
- (NSMutableArray <USMessageViewModel *>*) messageList {
    if(_messageList == nil) {
        _messageList = [NSMutableArray array];
        self.isLoadingMore = NO;
        self.hasMoreData = YES;
    }
    return _messageList;
}
- (USMessageViewModel *)viewModelAtIndexPath:(NSIndexPath *)indexPath{
    
    return self.messageList[indexPath.row];
    
}
- (NSString *)moreMsgId{
    if (self.messageList.count > 0 ) {
        return self.messageList[0].message.messageId;
    }
    return @"";
}
 
#pragma mark - action
- (void)themeAction:(id)sender{
    [USFeedbackTool impactSoft];

    USChatThemeController *vc = [[USChatThemeController alloc]init];
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)tapAction:(id)sender{
    [self.chatToolBar endEditing:YES];
    
}

- (void)refreshMsg:(NSArray<EMChatMessage *> *)messages
    isInsertBottom:(BOOL)isInsertBottom
    isScrollBottom:(BOOL)isScrollBottom{
    [self refreshMsg:messages isInsertBottom:isInsertBottom isScrollBottom:isScrollBottom animated:YES];
}



- (void)refreshMsg:(NSArray<EMChatMessage *> *)messages
    isInsertBottom:(BOOL)isInsertBottom
    isScrollBottom:(BOOL)isScrollBottom
          animated:(BOOL)animated
{
    NSMutableArray<USMessageViewModel *> *tempMsgs = [[NSMutableArray<USMessageViewModel *> alloc]init];
   
    
     for (EMChatMessage *message in messages) {
        if (message.body.type != EMMessageBodyTypeCmd) {
            
            if ([message.ext.allKeys containsObject:@"us_system"]) {
                if ([message.ext[@"us_system"] boolValue]  == YES) {
                    //系统消息不显示并且删除
                    [self.conversation removeMessagesFromServerMessageIds:@[message.messageId] completion:^(EMError * _Nullable aError) {
                        if (aError) {
                            NSLog(@"删除失败 -- %@",aError.errorDescription);
                        }
                    }];
                    continue;
                }
            }
            
            
            
            USMessageViewModel *model = [USMessageViewModel new];
            model.message = message;
            
            NSTimeInterval msgTime = message.localTime;
            if (message.direction == EMMessageDirectionReceive) {
                msgTime = message.timestamp;//接收方使用服务器消息
            }
            NSLog(@"msgTime = %lli",message.localTime);
            NSLog(@"msgTime = %lli",message.timestamp);
            CGFloat interval = (self.msgTimelTag - msgTime) / 1000;
            if (self.msgTimelTag < 0 || interval > 60 || interval < -60) {
                self.msgTimelTag = msgTime;
                model.showTime = YES;
            }
            
            [tempMsgs addObject:model];
        }
    }

    if (isInsertBottom) {
        [self.messageList addObjectsFromArray:tempMsgs];
        

        [self.tableView reloadData];
    }else{
        NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] firstObject];

        // 1. 记录第一个可见 cell 的 indexPath 和相对位置
        CGRect firstVisibleCellRect = [self.tableView rectForRowAtIndexPath:firstVisibleIndexPath];
        CGFloat offsetYBefore = self.tableView.contentOffset.y;
        CGFloat deltaY = firstVisibleCellRect.origin.y - offsetYBefore;
        
        
        [self.messageList insertObjects:tempMsgs atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, tempMsgs.count)]];
        
        NSMutableArray *indexPaths = [NSMutableArray array];
        for (NSInteger i = 0; i < tempMsgs.count; i++) {
            [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        }
        
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        
        // 4. 开始批量更新
        [self.tableView beginUpdates];
        [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];
        
        [self.tableView layoutIfNeeded];
        
        // 5. 计算插入后新的位置
        NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:firstVisibleIndexPath.row + tempMsgs.count inSection:0];
        CGRect newCellRect = [self.tableView rectForRowAtIndexPath:newIndexPath];
        CGFloat newOffsetY = newCellRect.origin.y - deltaY;
        
        // 6. 设置 contentOffset，还原滚动位置
        [self.tableView setContentOffset:CGPointMake(0, newOffsetY) animated:NO];
        
        [CATransaction commit];
    }
 
    if (isScrollBottom) {
        [self scrollToBottomAnimated:animated];
    }
    
}
- (void)insertSendMsg:(EMChatMessage *)message {
    
    USMessageViewModel *model = [USMessageViewModel new];
    model.message = message;
    
    CGFloat interval = (self.msgTimelTag - message.localTime) / 1000;
    if (self.msgTimelTag < 0 || interval > 60 || interval < -60) {
        self.msgTimelTag = message.localTime;
        model.showTime = YES;
    }
    [self.messageList addObject:model];
    
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messageList.count - 1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [self scrollToBottomAnimated:YES];
    
}

- (void)msgStatusDidChange:(EMChatMessage *)aMessage
                     error:(EMError *)aError {
    if (![self.conversation.conversationId isEqualToString:aMessage.conversationId]){
        return ;
    }
    
    @weakify(self)

    [self.messageList enumerateObjectsUsingBlock:^(USMessageViewModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        @strongify(self)
        if ([obj.message.messageId isEqualToString:aMessage.messageId]) {

            *stop = YES;
            if (idx != NSNotFound) {
                dispatch_async(dispatch_get_main_queue(), ^{

                    obj.cell.messageViewModel = obj;//刷新一下，不用reload，否则一条文本消息发送的时候reload，状态修改的时候reload，时间间隔太短，动画错乱
                    
                });
            }
        }
    }];
}
#pragma mark USStickerPickerViewDelegate
- (void)stickerPickerView:(USStickerPickerView *)picker didSelectSticker:(USStickerModel *)sticker{
    [self m_sendEmjoWithEmjoName:sticker.name];

}

#pragma mark - choosePhoto

- (void)photoAction:(UIButton *)sender{
    
    [USFeedbackTool impactMedium];
    
    DTItem *takePhoto = [DTItem itemWithTitle:@"拍照" image:[UIImage imageNamed:@"icon-camera-22"] tag:0 identifier:nil handle:^(DTItem *item) {
        [self takePhotoAction];
    }];
    
    DTItem *choosePhoto = [DTItem itemWithTitle:@"相册" image:[UIImage imageNamed:@"icon-photo-22"] tag:0 identifier:nil handle:^(DTItem *item) {
        [self presentImagePicker];
    }];
    
    
    DTTargetView *targetView = [[DTTargetView alloc]initWithTargetView:sender item:@[takePhoto,choosePhoto]];
    
    [targetView show];
    
}

- (void)takePhotoAction{
    
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        picker.delegate = self;
        picker.allowsEditing = NO; // 是否允许编辑
        [self presentViewController:picker animated:YES completion:nil];
    } else {
        [self.view us_makeAlert:@"当前设备不支持拍照" subTitle:nil];
    }
    
}

- (void)presentImagePicker {
    PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
    config.selectionLimit = 9;
    config.filter = [PHPickerFilter imagesFilter];
    PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
    picker.delegate = self;
    [self presentViewController:picker animated:YES completion:nil];
    
}

 // 代理回调
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results {
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    
    for (PHPickerResult *result in results) {
          NSItemProvider *provider = result.itemProvider;

          if ([provider canLoadObjectOfClass:[UIImage class]]) {
              [provider loadObjectOfClass:[UIImage class] completionHandler:^(UIImage *image, NSError *error) {
                  if (image && !error) {
                      dispatch_async(dispatch_get_main_queue(), ^{
                          [self sendImage:image];
                      });
                  }
              }];
          }
      }
 
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    
    NSData *data = UIImageJPEGRepresentation(image, 0.5);
    [self m_sendImageData:data size:image.size];
    
    [picker dismissViewControllerAnimated:YES completion:nil];
    
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissViewControllerAnimated:YES completion:nil];
}


- (void)sendImage:(UIImage *)image{
    
    NSData *data = UIImageJPEGRepresentation(image, 0.5);
    [self m_sendImageData:data size:image.size];
}


#pragma mark - <UITableViewDataSource,UITableViewDelegate>

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
   
    if (self.isLoadingMore || !self.hasMoreData || [self.moreMsgId isEqualToString: @""]) return;

    if (scrollView.contentOffset.y <= 80) {
        // 已接近顶部，加载更多历史记录
        self.isLoadingMore = YES;
        [self loadMessagesWithCompletion:^(NSArray<EMChatMessage *> *messages, NSError *error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                
                if (messages.count == 0) {
                    self.hasMoreData = NO;
                }else{
                    [self refreshMsg:messages isInsertBottom:NO isScrollBottom:NO animated:NO];

                }
                self.isLoadingMore = NO;
                
            });
        }];
    }
    
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    
    if (_stickerView.hidden == NO) {
        [self setIsEmjBarVisible:NO];
    }
    
    if (self.chatToolBar.textView.isFirstResponder) {
        [self.chatToolBar.textView resignFirstResponder];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    return self.messageList.count;
    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    USChatCell *cell = [USChatCellFactory cellForViewModel:[self viewModelAtIndexPath:indexPath] tableView:tableView indexPath:indexPath];
    
    cell.delegate = self;
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    
}

#pragma mark USChatCellDelegate
- (void)avatarDidSelected:(USMessageViewModel *)viewModel {
    USUserInfoViewController *vc = [[USUserInfoViewController alloc]init];
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)messageCellDidSelected:(USChatCell *)aCell {
    
    USMessageEventStrategy *eventStrategy = [USMessageEventStrategyFactory getStratrgyImplWithMsgType:aCell.messageViewModel.message.body.type];
    
    eventStrategy.chatController = self;
    
    [eventStrategy messageEventOperation:aCell.messageViewModel];
    
}

- (void)messageCellDidResend:(USChatCell *)cell {
    if (cell.messageViewModel.message.status == EMMessageStatusFailed) {
        
        @weakify(self)
        [[EMClient sharedClient].chatManager resendMessage:cell.messageViewModel.message progress:nil completion:^(EMChatMessage * _Nullable message, EMError * _Nullable error) {
           
            @strongify(self)
            [self msgStatusDidChange:message error:error];
            if (error) {
                [self.view makeToast:error.errorDescription];
            }
        }];
        
    }
}

- (void)messageCellDidLongPress:(USChatCell *)aCell bubbleView:(UIView *)bubbleView {
    [USFeedbackTool impactMedium];
    
    EMChatMessage *message = aCell.messageViewModel.message;
 
    DTItem *copy = [DTItem itemWithTitle:@"复制" image:[UIImage imageNamed:@"icon_copy"] tag:0 identifier:nil handle:^(DTItem *item) {
        [self menuCopyMessage:message];
    }];
    
    DTItem *delete = [DTItem itemWithTitle:@"删除" image:[UIImage imageNamed:@"icon-trash-22"] tag:0 identifier:nil handle:^(DTItem *item) {
        [self menuDeleteMessage:message];
    }];
    
    DTItem *withdraw = [DTItem itemWithTitle:@"撤回" image:[UIImage imageNamed:@"icon_undo"] tag:0 identifier:nil handle:^(DTItem *item) {
        [self menuRecallMessage:message];
    }];
    DTItem *save = [DTItem itemWithTitle:@"保存" image:[UIImage imageNamed:@"icon-photo-22"] tag:0 identifier:nil handle:^(DTItem *item) {

    }];
    DTItem *quote = [DTItem itemWithTitle:@"引用" image:[UIImage imageNamed:@"icon-photo-22"] tag:0 identifier:nil handle:^(DTItem *item) {

    }];
    
  
    NSMutableArray *arr = [NSMutableArray array];
    if (message.body.type == EMMessageBodyTypeText) {
        [arr addObjectsFromArray:@[copy,delete]];
    } else if (message.body.type == EMMessageBodyTypeVoice){
        [arr addObjectsFromArray:@[delete]];
    } else if (message.body.type == EMMessageBodyTypeImage || message.body.type == EMMessageBodyTypeVideo || message.body.type == EMMessageBodyTypeFile) {
        [arr addObjectsFromArray:@[save,delete]];
    } else {
        [arr addObjectsFromArray:@[delete]];
    }
    if (message.direction == EMMessageDirectionSend) {
        NSTimeInterval msgTime = message.localTime;
        CGFloat interval = [NSDate date].timeIntervalSince1970 - msgTime/1000;
        if (interval < 120) {
            [arr addObject:withdraw];
        }
    }
    
    NSLog(@"keyboardHeight =  %f",self.keyboardHeight);
    DTTargetView *targetView = [[DTTargetView alloc]initWithTargetView:bubbleView item:arr isChat:YES keyboardHeight:self.keyboardHeight];
    
    [targetView show];
    

}
- (void)menuCopyMessage:(EMChatMessage *)message{
    if (message.body.type == EMMessageBodyTypeText) {
        EMTextMessageBody *body = (EMTextMessageBody *)message.body;
        UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
        pasteboard.string = body.text;
    }
}
- (void)menuRecallMessage:(EMChatMessage *)message{
    @weakify(self)
    [self m_recallMessage:message Completion:^{
        @strongify(self)
        __block NSUInteger targetIndex = NSNotFound;
        [self.messageList enumerateObjectsUsingBlock:^(USMessageViewModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj.message.messageId isEqualToString:message.messageId]) {
                targetIndex = idx;
                *stop = YES;
            }
        }];
        
        if (targetIndex != NSNotFound) {
            
            EMCustomMessageBody *body = [[EMCustomMessageBody alloc]initWithEvent:@"recall" customExt:@{@"recallBy":[[EMClient sharedClient] currentUsername]}];
            EMChatMessage *recallMsg = [[EMChatMessage alloc]initWithConversationID:self.conversation.conversationId from:message.from to:message.to body:body ext:nil];

            recallMsg.chatType = (EMChatType)self.conversation.type;
            recallMsg.isRead = YES;
            recallMsg.localTime = message.localTime;
            recallMsg.timestamp = message.timestamp;
            [self.conversation insertMessage:recallMsg error:nil];

            
            USMessageViewModel *model = [USMessageViewModel new];
            model.message = recallMsg;
            
            [self.messageList replaceObjectAtIndex:targetIndex withObject:model];
            dispatch_async(dispatch_get_main_queue(), ^{
                //                     [self.tableView beginUpdates];
                [self.tableView reloadData];
                //                     [self.tableView endUpdates];
            });
        }
    }];
    
}
- (void)menuDeleteMessage:(EMChatMessage *)message{
    @weakify(self)
    [self m_deleteMessage:message Completion:^{
        @strongify(self)
        [self deleteMessage:message];
    }];
    
}

- (void)deleteMessage:(EMChatMessage *)message {
    __block NSUInteger targetIndex = NSNotFound;
    [self.messageList enumerateObjectsUsingBlock:^(USMessageViewModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.message.messageId isEqualToString:message.messageId]) {
            targetIndex = idx;
            *stop = YES;
        }
    }];
    
    if (targetIndex != NSNotFound) {
        [self.messageList removeObjectAtIndex:targetIndex];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:targetIndex inSection:0];
        
        dispatch_async(dispatch_get_main_queue(), ^{
                                 [self.tableView beginUpdates];
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                                 [self.tableView endUpdates];
        });
    }
}


@end
